/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lvyh.lightframe.job.admin.schedule.task;

import com.lvyh.lightframe.job.admin.bean.JobAlarmConfigBean;
import com.lvyh.lightframe.job.Constants;
import com.lvyh.lightframe.job.admin.common.JobInternalContext;
import com.lvyh.lightframe.job.admin.util.NetUtils;
import com.lvyh.lightframe.job.admin.util.SpringContextUtils;
import com.lvyh.lightframe.job.admin.manager.JobAdminBootstrap;
import com.lvyh.lightframe.job.admin.processor.JobManageProcessor;
import com.lvyh.lightframe.job.admin.service.MessageNotifyService;
import org.quartz.simpl.SimpleThreadPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;

/**
 * Scheduler resource check
 */
public class ResourceCheckTask implements Runnable {
    private final static Logger logger = LoggerFactory.getLogger(ResourceCheckTask.class);

    private boolean executorStoped;

    private JobManageProcessor jobManageProcessor;

    private MessageNotifyService messageNotifyService;

    public ResourceCheckTask() {
        this.executorStoped = JobAdminBootstrap.executorStoped;
        this.jobManageProcessor = SpringContextUtils.getBean(JobManageProcessor.class);
        this.messageNotifyService = SpringContextUtils.getBean(MessageNotifyService.class);
    }

    @Override
    public void run() {
        while (!executorStoped) {
            try {
                logger.info("[ResourceCheckTask] start to execute check task.");
                Thread.sleep(30000);
                //Thread.sleep(JobInternalContext.getJobCheckWaitTime());

                // Check whether the number of scheduler threads available is within the alarm range
                SimpleThreadPool simpleThreadPool = JobInternalContext.getThreadPool();
                int availableThreadCount = simpleThreadPool.blockForAvailableThreads();
                int maxThreadCount = JobInternalContext.getScheduleThreadCount();
                if (maxThreadCount <= 0) continue;

                //availableThreadCount = 1;
                float ratio = ((float) availableThreadCount / (float) maxThreadCount);

                // Check whether the thread resource reaches the limit
                if ((int) (ratio * 100) >= JobInternalContext.getScheduleIdleThreadPercent()) {
                    continue; // The alarm standard is not met
                }

                // Send alarm to administrator
                JobAlarmConfigBean alarmConfigBean = jobManageProcessor.getSystemAlarmConfigInfo();
                if (alarmConfigBean == null) {
                    continue;
                }

                String localIp = NetUtils.getLocalAddress().getHostAddress();
                String alarmContent = "Host IP：" + localIp +
                        ", Thread resource reached warning value:availableThreadCount-" + availableThreadCount +
                        ", maxThreadCount-" + maxThreadCount +
                        ", ThreadPercent-" + JobInternalContext.getScheduleIdleThreadPercent();


                HashMap<String, String> param = new HashMap<>();
                param.put("task_id", "-1");
                param.put("task_name", "Schedule system Resource monitoring");
                param.put("alarm_content", alarmContent);
                messageNotifyService.sendMessage(alarmConfigBean, param, Constants.EVENT_KEY_SCHEDULE_ALARM);

            } catch (Exception e) {
                logger.error("ResourceChecker execute error:{}", e.getMessage());
            }

        }
    }
}
